# -*- coding: utf-8 -*-
"""
金桔王业务逻辑处理节点
根据用户意图执行相应的业务逻辑处理
"""
import traceback
from agent.llm import llm, embeddings, cllm
from agent.agent_tools import read_help_document, list_help_documents, register_or_update_user, delete_user, upgrade_user_role, query_user
from common.log import logger
from common.enum_types import IntentionType, ActionType
from .workflow_utils import WorkflowState
from .prompt import BAVARDAR_PROMPT, HELP_PROMPT, KUMQUAT_INFO_PROMPT, MANAGE_USER_PROMPT


def _handle_help(state: WorkflowState) -> str:
    """处理帮助请求 - 使用工具调用机制"""
    try:
        # 获取ChatHandler实例
        chat_handler = state.get("chat_handler")
        if not chat_handler:
            logger.error("[📚帮助处理] ❌ ChatHandler不可用")
            return "😤 系统出错了！有什么事儿赶紧找管理员说！"
        
        # 使用ChatHandler获取提示词上下文
        user = state.get("user")
        chat_history = state.get("chat_history", [])
        prompt_context = chat_handler.get_prompt_context(user, chat_history)
        
        # 获取可用的帮助文档列表
        help_docs_result = list_help_documents.invoke({})
        help_docs_info = help_docs_result if isinstance(help_docs_result, str) else str(help_docs_result)
        
        # 构建帮助处理的提示词
        help_prompt = HELP_PROMPT.format(
            available_docs=help_docs_info,
            **prompt_context
        )

        logger.debug(f"[📚帮助处理] 🤖 LLM可用性: {cllm is not None}")
        
        if cllm:
            # 创建带工具的 LLM
            tools = [read_help_document, list_help_documents]
            llm_with_tools = cllm.bind_tools(tools)
            
            # 初始化消息序列
            from langchain_core.messages import HumanMessage
            messages = [HumanMessage(content=help_prompt)]
            
            # 支持多轮工具调用的循环
            max_iterations = 5  # 最大迭代次数，防止无限循环
            iteration = 0
            
            while iteration < max_iterations:
                iteration += 1
                logger.debug(f"[📚帮助处理] 🔄 第 {iteration} 轮调用")
                
                # 调用 LLM 生成回复
                response = llm_with_tools.invoke(messages)
                messages.append(response)  # 添加AI的回复到消息序列
                
                # 检查是否有工具调用
                if hasattr(response, 'tool_calls') and response.tool_calls:
                    logger.info(f"[📚帮助处理] 🔧 第 {iteration} 轮：AI请求调用 {len(response.tool_calls)} 个工具")
                    
                    # 执行工具调用并收集结果
                    tool_messages = []
                    for tool_call in response.tool_calls:
                        tool_name = tool_call['name']
                        tool_args = tool_call['args']
                        
                        logger.debug(f"[📚帮助处理] 🔧 调用工具: {tool_name} 参数: {tool_args}")
                        
                        # 执行工具并获取结果
                        if tool_name == 'read_help_document':
                            doc_name = tool_args.get('document_name', '未知文档')
                            chat_handler.add_action(f"READ_DOC:{doc_name}")
                            tool_result = read_help_document.invoke(tool_args)
                        elif tool_name == 'list_help_documents':
                            chat_handler.add_action("LIST_DOCS")
                            tool_result = list_help_documents.invoke(tool_args)
                        else:
                            chat_handler.add_action(f"UNKNOWN_TOOL:{tool_name}")
                            tool_result = f"未知工具: {tool_name}"
                        
                        # 创建工具消息
                        from langchain_core.messages import ToolMessage
                        tool_messages.append(ToolMessage(
                            content=str(tool_result),
                            tool_call_id=tool_call['id']
                        ))
                    
                    # 将工具结果添加到消息序列
                    messages.extend(tool_messages)
                    
                    # 继续下一轮循环，让AI基于工具结果决定下一步
                    continue
                else:
                    # 没有工具调用，说明AI已经生成了最终回复
                    response_text = response.content if hasattr(response, 'content') else str(response)
                    logger.info(f"[📚帮助处理] ✅ AI在第 {iteration} 轮生成最终回复")
                    return response_text.strip()
            
            # 如果达到最大迭代次数，返回最后一次的回复
            logger.warning(f"[📚帮助处理] ⚠️ 达到最大迭代次数 {max_iterations}，返回最后回复")
            if messages and hasattr(messages[-1], 'content'):
                return messages[-1].content.strip()
            else:
                return "📚 处理过程中遇到了一些问题，请稍后再试。"
        else:
            logger.warning(f"[📚帮助处理] ⚠️ LLM不可用，使用默认回复")
            return "😤 哎呀！我现在忙着呢，AI系统暂时不可用！有什么帮助需要的话，请稍后再试！"
            
    except Exception as e:
        logger.error(f"[📚帮助处理] ❌ 处理异常: {e} - {traceback.format_exc()}")
        return f"😤 烦死了！出错了！有什么事儿赶紧找管理员说：{traceback.format_exc()}"


def _handle_bavarder(state: WorkflowState) -> str:
    """处理闲聊请求"""
    try:
        # 获取ChatHandler实例
        chat_handler = state.get("chat_handler")
        if not chat_handler:
            logger.error("[闲聊处理] ❌ ChatHandler不可用")
            return "😤 系统出错了！有什么事儿赶紧说！"
        
        # 使用ChatHandler获取提示词上下文
        user = state.get("user")
        chat_history = state.get("chat_history", [])
        prompt_context = chat_handler.get_prompt_context(user, chat_history)
        
        chat_prompt = BAVARDAR_PROMPT.format(**prompt_context)
        
        logger.debug(f"[闲聊处理] 🤖 LLM可用性: {llm is not None}")
        
        if llm:
            response = llm.invoke(chat_prompt)
            response_text = response.content if hasattr(response, 'content') else str(response)
            return response_text.strip()
        else:
            logger.warning(f"[闲聊处理] ⚠️ LLM不可用，使用默认回复")
            return "😤 哎呀！我现在忙着呢，AI系统暂时不可用！有事儿就找管理员，别闲聊了！"
            
    except Exception as e:
        logger.error(f"[闲聊处理] ❌ 处理异常: {e} - {traceback.format_exc()}")
        return f"😤 烦死了！出错了！有事儿就找管理员说：{traceback.format_exc()}，别浪费时间！"


def _handle_kumquat_info(state: WorkflowState) -> str:
    """处理金桔信息查询请求 - 使用工具调用机制"""
    try:
        # 获取ChatHandler实例
        chat_handler = state.get("chat_handler")
        if not chat_handler:
            logger.error("[🍊金桔信息处理] ❌ ChatHandler不可用")
            return "😤 系统出错了！有什么事儿赶紧找管理员说！"
        
        # 使用ChatHandler获取提示词上下文
        user = state.get("user")
        chat_history = state.get("chat_history", [])
        prompt_context = chat_handler.get_prompt_context(user, chat_history)
        
        # 获取可用的帮助文档列表
        help_docs_result = list_help_documents.invoke({})
        available_docs = help_docs_result if isinstance(help_docs_result, str) else str(help_docs_result)
        
        # 构建金桔信息处理的提示词
        kumquat_info_prompt = KUMQUAT_INFO_PROMPT.format(
            available_docs=available_docs,
            **prompt_context
        )

        logger.debug(f"[🍊金桔信息处理] 🤖 LLM可用性: {cllm is not None}")
        
        if cllm:
            # 创建带工具的 LLM
            tools = [read_help_document, list_help_documents]
            llm_with_tools = cllm.bind_tools(tools)
            
            # 初始化消息序列
            from langchain_core.messages import HumanMessage
            messages = [HumanMessage(content=kumquat_info_prompt)]
            
            # 支持多轮工具调用的循环
            max_iterations = 5  # 最大迭代次数，防止无限循环
            iteration = 0
            
            while iteration < max_iterations:
                iteration += 1
                logger.debug(f"[🍊金桔信息处理] 🔄 第 {iteration} 轮调用")
                
                # 调用 LLM 生成回复
                response = llm_with_tools.invoke(messages)
                messages.append(response)  # 添加AI的回复到消息序列
                
                # 检查是否有工具调用
                if hasattr(response, 'tool_calls') and response.tool_calls:
                    logger.info(f"[🍊金桔信息处理] 🔧 第 {iteration} 轮：AI请求调用 {len(response.tool_calls)} 个工具")
                    
                    # 执行工具调用并收集结果
                    tool_messages = []
                    for tool_call in response.tool_calls:
                        tool_name = tool_call['name']
                        tool_args = tool_call['args']
                        
                        logger.debug(f"[🍊金桔信息处理] 🔧 调用工具: {tool_name} 参数: {tool_args}")
                        
                        # 执行工具并获取结果
                        if tool_name == 'read_help_document':
                            doc_name = tool_args.get('document_name', '未知文档')
                            chat_handler.add_action(f"READ_DOC:{doc_name}")
                            tool_result = read_help_document.invoke(tool_args)
                        elif tool_name == 'list_help_documents':
                            chat_handler.add_action("LIST_DOCS")
                            tool_result = list_help_documents.invoke(tool_args)
                        else:
                            chat_handler.add_action(f"UNKNOWN_TOOL:{tool_name}")
                            tool_result = f"未知工具: {tool_name}"
                        
                        # 创建工具消息
                        from langchain_core.messages import ToolMessage
                        tool_messages.append(ToolMessage(
                            content=str(tool_result),
                            tool_call_id=tool_call['id']
                        ))
                    
                    # 将工具结果添加到消息序列
                    messages.extend(tool_messages)
                    
                    # 继续下一轮循环，让AI基于工具结果决定下一步
                    continue
                else:
                    # 没有工具调用，说明AI已经生成了最终回复
                    response_text = response.content if hasattr(response, 'content') else str(response)
                    logger.info(f"[🍊金桔信息处理] ✅ AI在第 {iteration} 轮生成最终回复")
                    return response_text.strip()
            
            # 如果达到最大迭代次数，返回最后一次的回复
            logger.warning(f"[🍊金桔信息处理] ⚠️ 达到最大迭代次数 {max_iterations}，返回最后回复")
            if messages and hasattr(messages[-1], 'content'):
                return messages[-1].content.strip()
            else:
                return "🍊 处理过程中遇到了一些问题，请稍后再试。"
        else:
            logger.warning(f"[🍊金桔信息处理] ⚠️ LLM不可用，使用默认回复")
            return "🍊 金桔是很棒的水果！有什么具体想了解的吗？系统出了点小问题，暂时不能回答您的问题。"
            
    except Exception as e:
        logger.error(f"[🍊金桔信息处理] ❌ 处理异常: {e} - {traceback.format_exc()}")
        return f"🍊 金桔是很棒的水果！有什么具体想了解的吗？系统出了点小问题：{traceback.format_exc()}"


def _handle_manage_user(state: WorkflowState) -> str:
    """处理用户管理请求 - 使用工具调用机制"""
    try:
        # 获取ChatHandler实例
        chat_handler = state.get("chat_handler")
        if not chat_handler:
            logger.error("[👤用户管理] ❌ ChatHandler不可用")
            return "❌ 系统出错了！有什么事儿赶紧找管理员说！"
        
        # 使用ChatHandler获取提示词上下文
        user = state.get("user")
        chat_history = state.get("chat_history", [])
        prompt_context = chat_handler.get_prompt_context(user, chat_history)

        # 构建用户管理处理的提示词
        manage_user_prompt = MANAGE_USER_PROMPT.format(**prompt_context)
        logger.info(f"[👤用户管理] 📝 用户管理提示词: {manage_user_prompt}")

        logger.debug(f"[👤用户管理] 🤖 LLM可用性: {cllm is not None}")
        
        if cllm:
            # 🔧 创建包装函数来处理chat_handler参数传递
            def wrapped_register_or_update_user(name: str = None, phone: str = None, address: str = None, target_nickname: str = None) -> str:
                """注册新用户或修改现有用户信息，自动传递chat_handler进行身份验证"""
                return register_or_update_user(name=name, phone=phone, address=address, target_nickname=target_nickname, chat_handler=chat_handler)
            
            def wrapped_delete_user(target_nickname: str) -> str:
                """删除用户，自动传递chat_handler进行身份验证和权限检查"""
                return delete_user(chat_handler=chat_handler, target_nickname=target_nickname)
            
            def wrapped_upgrade_user_role(target_nickname: str, new_role: str) -> str:
                """升级用户角色，自动传递chat_handler进行身份验证和权限检查"""
                return upgrade_user_role(chat_handler=chat_handler, target_nickname=target_nickname, new_role=new_role)
            
            def wrapped_query_user(target_name: str = None) -> str:
                """查询用户信息 - 支持模糊搜索姓名和昵称，自动传递chat_handler进行身份验证和权限检查"""
                return query_user(chat_handler=chat_handler, target_name=target_name)
            
            # 为包装函数添加工具装饰器
            from langchain_core.tools import tool
            wrapped_register_or_update_user = tool(wrapped_register_or_update_user)
            wrapped_delete_user = tool(wrapped_delete_user)
            wrapped_upgrade_user_role = tool(wrapped_upgrade_user_role)
            wrapped_query_user = tool(wrapped_query_user)
            
            # 创建带工具的 LLM - 只提供包装后的工具函数，不再提供原始的SQL工具
            tools = [wrapped_register_or_update_user, wrapped_delete_user, wrapped_upgrade_user_role, wrapped_query_user]
            llm_with_tools = cllm.bind_tools(tools)
            
            # 初始化消息序列
            from langchain_core.messages import HumanMessage
            messages = [HumanMessage(content=manage_user_prompt)]
            
            # 支持多轮工具调用的循环
            max_iterations = 5  # 最大迭代次数，防止无限循环
            iteration = 0
            
            while iteration < max_iterations:
                iteration += 1
                logger.debug(f"[👤用户管理] 🔄 第 {iteration} 轮调用")
                
                # 调用 LLM 生成回复
                response = llm_with_tools.invoke(messages)
                messages.append(response)  # 添加AI的回复到消息序列
                
                # 检查是否有工具调用
                if hasattr(response, 'tool_calls') and response.tool_calls:
                    logger.info(f"[👤用户管理] 🔧 第 {iteration} 轮：AI请求调用 {len(response.tool_calls)} 个工具")
                    
                    # 执行工具调用并收集结果
                    tool_messages = []
                    for tool_call in response.tool_calls:
                        tool_name = tool_call['name']
                        tool_args = tool_call['args']
                        
                        logger.debug(f"[👤用户管理] 🔧 调用工具: {tool_name} 参数: {tool_args}")
                        
                        # 执行工具并获取结果
                        if tool_name == 'wrapped_register_user':
                            chat_handler.add_action("USER_MGMT:REGISTER_USER")
                            tool_result = wrapped_register_user.invoke(tool_args)
                        elif tool_name == 'wrapped_delete_user':
                            chat_handler.add_action("USER_MGMT:DELETE_USER")
                            tool_result = wrapped_delete_user.invoke(tool_args)
                        elif tool_name == 'wrapped_upgrade_user_role':
                            chat_handler.add_action("USER_MGMT:UPGRADE_USER_ROLE")
                            tool_result = wrapped_upgrade_user_role.invoke(tool_args)
                        elif tool_name == 'wrapped_query_user':
                            chat_handler.add_action("USER_MGMT:QUERY_USER")
                            tool_result = wrapped_query_user.invoke(tool_args)
                        else:
                            chat_handler.add_action(f"UNKNOWN_TOOL:{tool_name}")
                            tool_result = f"未知工具: {tool_name}"
                        
                        # 创建工具消息
                        from langchain_core.messages import ToolMessage
                        tool_messages.append(ToolMessage(
                            content=str(tool_result),
                            tool_call_id=tool_call['id']
                        ))
                    
                    # 将工具结果添加到消息序列
                    messages.extend(tool_messages)
                    
                    # 继续下一轮循环，让AI基于工具结果决定下一步
                    continue
                else:
                    # 没有工具调用，说明AI已经生成了最终回复
                    response_text = response.content if hasattr(response, 'content') else str(response)
                    logger.info(f"[👤用户管理] ✅ AI在第 {iteration} 轮生成最终回复")
                    return response_text.strip()
            
            # 如果达到最大迭代次数，返回最后一次的回复
            logger.warning(f"[👤用户管理] ⚠️ 达到最大迭代次数 {max_iterations}，返回最后回复")
            if messages and hasattr(messages[-1], 'content'):
                return messages[-1].content.strip()
            else:
                return "👤 处理过程中遇到了一些问题，请稍后再试。"
        else:
            logger.warning(f"[👤用户管理] ⚠️ LLM不可用，使用默认回复")
            return "👤 用户管理功能暂时不可用，请稍后再试。"
            
    except Exception as e:
        logger.error(f"[👤用户管理] ❌ 处理异常: {e} - {traceback.format_exc()}")
        return f"👤 用户管理处理出现问题：{e} - {traceback.format_exc()}"


def _format_query_result(result: list) -> str:
    """格式化查询结果"""
    if not result or len(result) == 0:
        return "❌ 未找到相关用户信息"
    
    if len(result) == 1:
        user = result[0]
        return f"""📋 用户信息
👤 姓名：{user.get('name', '未知')}
📱 手机：{user.get('phone', '未知')}
📍 地址：{user.get('address', '未设置')}
🎭 角色：{user.get('role', 'USER')}
📅 注册时间：{user.get('created_at', '未知')}
🔄 更新时间：{user.get('updated_at', '未知')}"""
    else:
        # 多个用户结果
        result_text = "📋 用户列表\n"
        for i, user in enumerate(result, 1):
            result_text += f"\n{i}. 👤 {user.get('name', '未知')} 📱 {user.get('phone', '未知')} 🎭 {user.get('role', 'USER')}"
        return result_text


def handle_empty_instruction(wx_msg: dict, user: dict) -> str:
    """处理空指令"""
    return "❓ 请告诉我您需要什么帮助，我可以为您提供金桔相关信息、订单管理等服务。"


def handle_other_intentions(intention: str, wx_msg: dict, user: dict) -> str:
    """
    处理其他意图的业务逻辑
    
    Args:
        intention: 意图类型
        wx_msg: 微信消息
        user: 用户信息
    
    Returns:
        处理结果
    """
    # 根据不同意图处理不同的业务逻辑
    if intention == "ORDER_MANAGEMENT":
        return f"""
📋 **个人订单管理** 📋

**当前订单：**
• 订单号：KQ2024001
• 品种：脆蜜金桔
• 数量：50斤
• 状态：待发货

**历史订单：**
• 本月已完成：3单
• 累计购买：280斤

（这是Mock数据，实际数据需要连接数据库）
        """.strip()
        
    elif intention == "REPORT_ORDERS":
        return f"""
📈 **销售报告** 📈

**本周统计：**
• 总订单：125单
• 总重量：2,450斤
• 平均单价：19.6斤/单

**品种分布：**
• 脆蜜金桔：60%
• 滑皮金桔：35%
• 其他：5%

（这是Mock数据，实际数据需要连接数据库）
        """.strip()
        
    else:
        return f"🔧 正在处理 {intention} 操作，请稍候..."


def business_logic_node(state: WorkflowState) -> dict:
    """
    业务逻辑处理节点
    根据意图类型执行相应的业务逻辑
    """
    try:
        intention = state.get("intention", IntentionType.BAVARDER.value)
        chat_handler = state.get("chat_handler")
        
        logger.info(f"[🏢业务逻辑] 开始处理意图: {intention}")
        
        # 根据意图类型执行相应的业务逻辑
        if intention == IntentionType.HELP.value:
            result = _handle_help(state)
        elif intention == IntentionType.BAVARDER.value:
            result = _handle_bavarder(state)
        elif intention == IntentionType.KUMQUAT_INFO.value:
            result = _handle_kumquat_info(state)
        elif intention == IntentionType.MANAGE_USER.value:
            result = _handle_manage_user(state)
        elif intention == IntentionType.MANAGE_MY_ORDER.value:
            result = handle_other_intentions(intention, state.get("wx_msg", {}), state.get("user", {}))
        elif intention == IntentionType.REPORT_TODAY.value:
            result = handle_other_intentions(intention, state.get("wx_msg", {}), state.get("user", {}))
        elif intention == IntentionType.REPORT_ORDERS.value:
            result = handle_other_intentions(intention, state.get("wx_msg", {}), state.get("user", {}))
        elif intention == IntentionType.CHECK_MY_ORDERS.value:
            result = handle_other_intentions(intention, state.get("wx_msg", {}), state.get("user", {}))
        elif intention == IntentionType.CHECK_MY_KUMQUATS.value:
            result = handle_other_intentions(intention, state.get("wx_msg", {}), state.get("user", {}))
        elif intention == IntentionType.KUMQUAT_MANAGE.value:
            result = handle_other_intentions(intention, state.get("wx_msg", {}), state.get("user", {}))
        else:
            # 未知意图，默认为闲聊
            logger.warning(f"[🏢业务逻辑] 未知意图类型: {intention}，默认为闲聊")
            result = _handle_bavarder(state)
        
        # 记录业务逻辑处理完成
        if chat_handler:
            chat_handler.add_action(ActionType.with_context(ActionType.BUSINESS_COMPLETE, intention))
        
        logger.info(f"[🏢业务逻辑] 意图 {intention} 处理完成")
        
        return {
            **state,
            "final_response": result,  # 设置 final_response 为处理结果
            "workflow_status": "business_completed"
        }
        
    except Exception as e:
        error_msg = f"业务逻辑处理失败: {e} - {traceback.format_exc()}"
        logger.error(f"[🏢业务逻辑] {error_msg}")
        
        chat_handler = state.get("chat_handler")
        if chat_handler:
            chat_handler.add_action(ActionType.BUSINESS_ERROR.value)
            chat_handler.set_note(f"业务逻辑处理异常: {str(e)}")
        
        return {
            **state,
            "error": error_msg,
            "final_response": "系统处理异常，请稍后重试",
            "workflow_status": "business_error"
        }